﻿// -----------------------------------------------------------------------
// <copyright file="TextHandler.cs" company="Microsoft">
// Proccessing text data handler
// </copyright>
// -----------------------------------------------------------------------
namespace WebServer.BusinessLogic.Handlers
{
    using System.Text;
    using WebServer.BusinessLogic.Handlers.Interface;
    using WebServer.BusinessLogic.Helpers;
    using WebServer.BusinessLogic.Web;

    /// <summary>
    /// Handles Text Requests
    /// </summary>
    public class TextHandler : Handler
    {
        /// <summary>
        /// interface for testing
        /// </summary>
        private IFileSystemProvider _fileSystemProvider;

        /// <summary>
        /// Create object TextHandler using IFileSystemProvider interface
        /// </summary>
        /// <param name="fs">fake interface for testing</param>
        public TextHandler(IFileSystemProvider fs)
        {
            _fileSystemProvider = fs;
        }

        /// <summary>
        /// Real File System constructor
        /// </summary>
        public TextHandler()
        {
            _fileSystemProvider = new FileSystemProvider();
        }

        /// <summary>
        /// Tries to handle request.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The WebServer.BusinessLogic.Response.
        /// </returns>
        public override Response Handle(Request request)
        {
            string ext = request.HttpPath.ToLower();
            if (ext.EndsWith(".html") || ext.EndsWith(".htm") || ext.EndsWith(".css")
                || ext.EndsWith(".js"))
            {
                string filePath = Configurator.Instance.RelativeWwwPath + request.HttpPath.Replace("/", "\\");

                if (!_fileSystemProvider.FileExists(filePath))
                {
                    return this.NextHandler.Handle(request);
                }

                string cacheKey = request.HttpPath;
                byte[] data = _fileSystemProvider.GetDataOrFile(cacheKey, filePath);

                // process text (SSI, Admin Panel)
                data = ProcessData(data, request);

                // zip and push
                string MIMEType = IdentifyContentType(request);
                string version = request.HttpVersion;

                Response toReturn = new Response(MIMEType, version, data);
                if (Configurator.Instance.UseResponseCompression && request.AcceptEncoding == EnumAcceptEncoding.Gzip)
                {
                    toReturn.Data = GzipCompress(toReturn.Data);
                    toReturn.ContentEncoding = "gzip";
                }

                return toReturn;
            }

            return this.NextHandler.Handle(request);
        }

        /// <summary>
        /// Processing data with SsiParcer and AdminPanel
        /// </summary>
        /// <param name="data">data  of text file</param>
        /// <param name="request">incoming request</param>
        /// <returns>modified outcoming data for response</returns>
        private byte[] ProcessData(byte[] data, Request request)
        {
            // we have to decode and encode data to insert dynamic content
            string text = Encoding.UTF8.GetString(data);

            var session = SessionManager.Instance.GetCurrentSession(request);
            if (session != null && session.IsAdmin)
            {
                // VK: why is TextHandler handling admin page loading?
                // we've read requested file once, and after that we're AGAIN reading settings.html ...
                // if (request.HttpPath.EndsWith("admin/index.html"))
                // {
                //    string filePath = Configurator.Instance.RelativeWwwPath + "\\admin\\settings.html";
                //    text = File.ReadAllText(filePath);
                // }
                // else
                // {
                    text = ReplaceWithAdminPanel(text);
                // }
            }
            var ssiParser = new SsiParser();
            text = ssiParser.ParseSsi(text, request);

            return Encoding.UTF8.GetBytes(text);
        }

        /// <summary>
        /// Showing that admin is loggined
        /// </summary>
        /// <param name="text">text of text html page</param>
        /// <returns>text with modified body</returns>
        private string ReplaceWithAdminPanel(string text)
        {
            return text.Replace("<body>", string.Format("<body>\r\n[Administrator logged in. <a href=\"{0}\">Logout</a>]<br />\r\n", AdminHandler.AdminLogoutPage.TrimStart(new[] {'/'})));
        }
    }
}
